/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-08-25     wyj       the first version
 */
#ifndef _DATA_SAVE_HPP_
#define _DATA_SAVE_HPP_

#include <vector>
#include "drivers_module.hpp"



typedef enum
{
    data_save_status_ok,
    data_save_status_fail,
    data_save_status_not_init,
    data_save_status_dead_error,
} data_save_status;

typedef enum
{
    data_save_type_uint32_t,
    data_save_type_uint16_t,
    data_save_type_uint8_t,
    data_save_type_int32_t,
    data_save_type_int16_t,
    data_save_type_int8_t,
    data_save_type_float_t,
} data_save_type;

typedef union
{
    uint32_t _u32;
    uint16_t _u16;
    uint8_t _u8;
    int32_t _s32;
    int16_t _s16;
    int8_t _s8;
    float_t _f32;
} data_save_buff;

class _DATA_VECTOR
{
public:
    std::string name;
    data_save_buff data_buff;
    data_save_type data_type;
public:
    _DATA_VECTOR(std::string name, data_save_type data_type);
    _DATA_VECTOR(const _DATA_VECTOR &p);
};
/*
 * EEPROM写入顺序：
 * 写入数据
 * 更新写入数据位置
 *
 * 数据保存的格式为：
 * 0-127 ：保存最新页数的地址，从0开始存，每两位组合为一个16位无符号值代表最新数据保存在的页数
 * 每次写入新的数据，地址递增2
 * 如刚开始页数数据写在0和1，内容为1，代表最新数据写在第一页（对应地址128-255）
 * 第二次写入的页数为2，页数据保存的地址位2和3，以此类推
 * 使用BL24C512时，最大页数为512，即页数数据在1-511循环,第0页用于储存最新页数信息，故不参与循环
 */
class DATA_SAVE
{
private:
    EEPROM *eeprom;
    std::vector<_DATA_VECTOR> short_cycle_data_vector;
    rt_mutex_t short_cycle_data_vector_lock;
    std::vector<_DATA_VECTOR> long_cycle_data_vector;
    rt_mutex_t long_cycle_data_vector_lock;

    uint32_t short_cycle_data_start_page; //实时数据开始的页数
    uint32_t short_cycle_data_page_num; //实时数据的页数量
    uint32_t short_cycle_mines_bytes;
    uint32_t short_cycle_data_bytes_length; //实时数据记录的长度//（不包含索引长度）
    uint32_t now_newest_short_cycle_data_addr; //最新实时数据的起始地址

    uint32_t long_cycle_data_start_page; //长周期日志数据开始的页数
    uint32_t long_cycle_data_page_num; //长周期日志数据的页数量
    uint32_t long_cycle_data_bytes_length; //长周期日志数据记录的长度（列如：1min记录一次的数据）
    uint32_t now_newest_long_cycle_data_addr; //最新长周期日志数据的起始地址

    uint32_t config_start_page; //配置区开始的页数(暂未用到)
    uint32_t config_page_num; //配置区的页数量(暂未用到)

    data_save_status init_flag;
    uint8_t debug_flag;

    uint8_t _u8_buff_transfer_to_u8(uint8_t* buff);
    uint16_t _u8_buff_transfer_to_u16(uint8_t* buff);
    uint32_t _u8_buff_transfer_to_u32(uint8_t* buff);
    int8_t _u8_buff_transfer_to_s8(uint8_t* buff);
    int16_t _u8_buff_transfer_to_s16(uint8_t* buff);
    int32_t _u8_buff_transfer_to_s32(uint8_t* buff);
    float_t _u8_buff_transfer_to_float(uint8_t* buff);

    void _u8_transfer_to_u8_buff(uint8_t* out_buff, uint8_t u8);
    void _u16_transfer_to_u8_buff(uint8_t* out_buff, uint16_t u16);
    void _u32_transfer_to_u8_buff(uint8_t* out_buff, uint32_t u32);
    void _s8_transfer_to_u8_buff(uint8_t* out_buff, int8_t s8);
    void _s16_transfer_to_u8_buff(uint8_t* out_buff, int16_t s16);
    void _s32_transfer_to_u8_buff(uint8_t* out_buff, int32_t s32);
    void _float_transfer_to_u8_buff(uint8_t* out_buff, float_t f);
public:
    DATA_SAVE(EEPROM *eeprom,
              uint32_t config_start_page,
              uint32_t config_page_num,
              uint32_t short_cycle_data_start_page,
              uint32_t short_cycle_data_page_num,
              uint32_t long_cycle_data_start_page,
              uint32_t long_cycle_data_page_num);
    ~DATA_SAVE();
    void DATA_SAVE_open_debug();

    data_save_status DATA_SAVE_factory_init(); //初始化并清除所有已存在信息，当注册数据不同时（包括顺序不同、个数不同、种类不同），应当运行一次该函数
    data_save_status DATA_SAVE_init(); //正常启动，读取并继承信息,init前应当注册所有数据

    data_save_status DATA_SAVE_record_short_cycle_data(); //将实时数据写入eeprom
    data_save_status DATA_SAVE_record_long_cycle_data(); //将日志记录数据写入eeprom
    //注册实时数据,init前应当使用该函数注册所有数据
    data_save_status DATA_SAVE_short_cycle_registe_data(std::string name, data_save_type data_type);
    //注册记录数据,init前应当使用该函数注册所有数据
    data_save_status DATA_SAVE_long_cycle_registe_data(std::string name, data_save_type data_type);

    //写入vector中的一个值

    data_save_status DATA_SAVE_write_short_cycle_data(std::string name, uint32_t write_data);
    data_save_status DATA_SAVE_write_short_cycle_data(std::string name, uint16_t write_data);
    data_save_status DATA_SAVE_write_short_cycle_data(std::string name, uint8_t write_data);
    data_save_status DATA_SAVE_write_short_cycle_data(std::string name, int32_t write_data);
    data_save_status DATA_SAVE_write_short_cycle_data(std::string name, int16_t write_data);
    data_save_status DATA_SAVE_write_short_cycle_data(std::string name, int8_t write_data);
    data_save_status DATA_SAVE_write_short_cycle_data(std::string name, float_t write_data);

    data_save_status DATA_SAVE_write_long_cycle_data(std::string name, uint32_t write_data);
    data_save_status DATA_SAVE_write_long_cycle_data(std::string name, uint16_t write_data);
    data_save_status DATA_SAVE_write_long_cycle_data(std::string name, uint8_t write_data);
    data_save_status DATA_SAVE_write_long_cycle_data(std::string name, int32_t write_data);
    data_save_status DATA_SAVE_write_long_cycle_data(std::string name, int16_t write_data);
    data_save_status DATA_SAVE_write_long_cycle_data(std::string name, int8_t write_data);
    data_save_status DATA_SAVE_write_long_cycle_data(std::string name, float_t write_data);

    //读出vector中的一个值
    data_save_status DATA_SAVE_read_short_cycle_data(std::string name, uint32_t* read_data);
    data_save_status DATA_SAVE_read_short_cycle_data(std::string name, uint16_t* read_data);
    data_save_status DATA_SAVE_read_short_cycle_data(std::string name, uint8_t* read_data);
    data_save_status DATA_SAVE_read_short_cycle_data(std::string name, int32_t* read_data);
    data_save_status DATA_SAVE_read_short_cycle_data(std::string name, int16_t* read_data);
    data_save_status DATA_SAVE_read_short_cycle_data(std::string name, int8_t* read_data);
    data_save_status DATA_SAVE_read_short_cycle_data(std::string name, float_t* read_data);

    data_save_status DATA_SAVE_read_long_cycle_data(std::string name, uint32_t* read_data);
    data_save_status DATA_SAVE_read_long_cycle_data(std::string name, uint16_t* read_data);
    data_save_status DATA_SAVE_read_long_cycle_data(std::string name, uint8_t* read_data);
    data_save_status DATA_SAVE_read_long_cycle_data(std::string name, int32_t* read_data);
    data_save_status DATA_SAVE_read_long_cycle_data(std::string name, int16_t* read_data);
    data_save_status DATA_SAVE_read_long_cycle_data(std::string name, int8_t* read_data);
    data_save_status DATA_SAVE_read_long_cycle_data(std::string name, float_t* read_data);

    data_save_status DATA_SAVE_read_init_status();
    void DATA_SAVE_print_now_all_data();
};

#endif /* _DATA_SAVE_HPP_ */
